<script lang="tsx" setup>

import type {BbsCodeNode} from "../../network/types/BbsCodeNode.ts";
import UserRoute from "../routes/UserRoute.vue";
import TopicReadRoute from "../routes/TopicReadRoute.vue";
import {ElButton, ElCarousel, ElCarouselItem, ElLink} from "element-plus";
import NgaCollapse from "./NgaCollapse.vue";
import NgaText from "./NgaText.vue";
import NgaImage from "./NgaImage.vue";
import NgaUrl from "./NgaUrl.vue";
import NgaTd from "./NgaTd.vue";
import {Codemirror} from "vue-codemirror";
import {toNumber} from "../../utils/Utils.ts";

interface Props {
  data: BbsCodeNode[]
}

const emit = defineEmits(["SingleReply"])

const props = defineProps<Props>()

interface Renders {
  [key: string]: (node: BbsCodeNode) => any
}

const renders: Renders = {
  quote: (node) => <div class="nga-quote">{render(node.children)}</div>,
  heading: (node) => <h4>{render(node.children)}</h4>,
  ul: (node) => <ul>{render(node.children)}</ul>,
  li: (node) => <li>{render(node.children)}</li>,
  bold: (node) => <span class="bold">{render(node.children)}</span>,
  italic: (node) => <span class="italic">{render(node.children)}</span>,
  del: (node) => <span class="line-through">{render(node.children)}</span>,
  underline: (node) => <span class="underline">{render(node.children)}</span>,
  color: (node) => <span style={'color: ' + node.params}>{render(node.children)}</span>,
  size: (node) => <span style={'font-size: ' + node.params}>{render(node.children)}</span>,
  font: (node) => <span style={'font-family:' + node.params}>{render(node.children)}</span>,
  align: (node) => <span style={'display:block;text-align:' + node.params}>{render(node.children)}</span>,
  left: (node) => <span style={'display:block;float:left'}>{render(node.children)}</span>,
  right: (node) => <span style={'display:block;float:right'}>{render(node.children)}</span>,
  pid: (node) => {
    const [pid, tid, page] = node.params!!.split(',').map(Number)
    if (page) {
      return <>
        <ElButton type="primary" size="small" onClick={() => emit('SingleReply', pid)}>R</ElButton>
        <TopicReadRoute tid={tid} page={page} hash={'#P' + pid}>
          [ {render(node.children)} ]
        </TopicReadRoute>
      </>
    }
    return <TopicReadRoute pid={pid}>[ {render(node.children)} ]</TopicReadRoute>
  },
  table: (node) => <table class="nga-table">
    <tbody>{render(node.children)}</tbody>
  </table>,
  tr: (node) => <tr>{render(node.children)}</tr>,
  td: (node) => <NgaTd params={node.params || ""}>{render(node.children)}</NgaTd>,
  uid: (node) => <UserRoute user-id={Number(node.params)}>[ {render(node.children)} ]</UserRoute>,
  at: (node) => {
    if (isNaN(toNumber(node.params) || Number(''))) {
      return <UserRoute username={node.params}>[@{node.params}]</UserRoute>
    }
    return <UserRoute user-id={node.params}>[@{node.params}]</UserRoute>
  },
  collapse: (node) => <NgaCollapse node={node}>{render(node.children)}</NgaCollapse>,
  img: (node) => <NgaImage uri={node.params || ""}/>,
  tid: (node) => <TopicReadRoute tid={Number(node.params)}>[ {render(node.children)} ]</TopicReadRoute>,
  url: (node) => <NgaUrl url={node.params || ""}>[ {render(node.children)} ]</NgaUrl>,
  dice: (node) => <div class="dice-div"><span class="dice-result">{node.text}</span></div>,
  code: (node) => <Codemirror v-model={node.text} disabled/>,
  randomblocks: (node) => <ElCarousel trigger="click" height="150px">{render(node.children)}</ElCarousel>,
  randomblock: (node) => <ElCarouselItem>{render(node.children)}</ElCarouselItem>,
  flash: (node) => {
    const u = node.params
    if (!u) return <span>缺少参数</span>
    if (u.startsWith("http")) {
      const bv = /bilibili\.com\/video\/(BV.+)/.exec(u)?.[1]?.replace('/', '')
      if (bv) {
        return <iframe height="499" width="892" src={`https://player.bilibili.com/player.html?bvid=${bv}`} allowfullscreen/>
      }
      return <NgaUrl url={u}>{u}</NgaUrl>
    }
    return <iframe src={u.replace('./', '/static/attach/attachments/')} sandbox=""/>
  },
  attach: (node) => {
    const u = node.params?.replace('./', '/static/attach/attachments/')
    if (!u) return <span>缺少参数</span>
    const title = decodeURI(/filename=(.+)/.exec(u)?.[1] || "")
    return <ElLink href={u}>下载附件: {title}</ElLink>
  },
  text: (node) => <NgaText text={node.text || ""}/>,
  raw: (node) => <>
    [{node.type}]
    {render(node.children)}
    [/{node.type}]
  </>,
}

// text: (node) => <span v-html={node.text?.replace(/\n/g, '<br/>')}></span>,

const render = (nodes: BbsCodeNode[] | undefined) => {
  if (!nodes) return []
  // console.log("nodes", nodes)
  return nodes.map(node => {
    if (renders[node.type]) {
      return renders[node.type](node)
    } else {
      return renders.raw(node)
    }
  })
}

const r = () => render(props.data)
</script>

<template>
  <r/>
</template>

<style scoped>

</style>